package lab;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;

public class GenerateurLab
{
	public final static int TAILLE = 10;
	public final static int TAILLE_ROOM = 7;

	public boolean[][] getlabyrinthe()
	{
		Cell[][] tabCell = new Cell[TAILLE][TAILLE];
		// boucle initialiation des cellulles
		for ( int i = 0; i < tabCell[0].length; i++ )
		{
			for ( int j = 0; j < tabCell.length; j++ )
			{
				tabCell[i][j] = new Cell( i, j );
			}
		}
		// Pile des cellules
		Stack<Cell> test = new Stack<Cell>();
		Cell depCell = tabCell[0][0];
		depCell.visited = true;
		test.add( depCell );
		while ( !test.isEmpty() )
		{
			Cell currentCell = test.peek();
			List<Cell> cellPossible = getPossibleNextCell( currentCell ,
					tabCell );
			if ( cellPossible.isEmpty() )
			{
				test.pop();
			}
			else
			{
				int choix = (int) ((new Random().nextDouble() * (double) cellPossible
						.size()));
				Cell newCell = cellPossible.get( choix );
				newCell.visited = true;
				if ( currentCell.x + 1 == newCell.x )
				{
					currentCell.east = true;
					newCell.west = true;
				}
				if ( currentCell.x - 1 == newCell.x )
				{
					currentCell.west = true;
					newCell.east = true;
				}
				if ( currentCell.y - 1 == newCell.y )
				{
					currentCell.north = true;
					newCell.south = true;
				}
				if ( currentCell.y + 1 == newCell.y )
				{
					currentCell.south = true;
					newCell.north = true;
				}
				test.add( newCell );
			}
		}
		return getMap( tabCell );
	}

	private List<Cell> getPossibleNextCell( Cell pCurrentCell ,
			Cell[][] pTabCell )
	{
		List<Cell> result = new ArrayList<Cell>();
		if ( pCurrentCell.x - 1 >= 0
				&& !pTabCell[pCurrentCell.x - 1][pCurrentCell.y].visited )
		{
			result.add( pTabCell[pCurrentCell.x - 1][pCurrentCell.y] );
		}
		if ( pCurrentCell.x + 1 < TAILLE
				&& !pTabCell[pCurrentCell.x + 1][pCurrentCell.y].visited )
		{
			result.add( pTabCell[pCurrentCell.x + 1][pCurrentCell.y] );
		}
		if ( pCurrentCell.y - 1 >= 0
				&& !pTabCell[pCurrentCell.x][pCurrentCell.y - 1].visited )
		{
			result.add( pTabCell[pCurrentCell.x][pCurrentCell.y - 1] );
		}
		if ( pCurrentCell.y + 1 < TAILLE
				&& !pTabCell[pCurrentCell.x][pCurrentCell.y + 1].visited )
		{
			result.add( pTabCell[pCurrentCell.x][pCurrentCell.y + 1] );
		}
		return result;
	}

	private boolean[][] getMap( Cell[][] pTabCell )
	{
		boolean[][] result = new boolean[TAILLE * TAILLE_ROOM][TAILLE
				* TAILLE_ROOM];
		// boucle init
		for ( int i = 0; i < result[0].length; i++ )
		{
			for ( int j = 0; j < result.length; j++ )
			{
				result[i][j] = false;
			}
		}
		// remplissage
		for ( int i = 0; i < pTabCell[0].length; i++ )
		{
			for ( int j = 0; j < pTabCell.length; j++ )
			{
				Cell currentCell = pTabCell[i][j];
				/*
				 * int xc = i * TAILLE_ROOM + 1; int yc = j * TAILLE_ROOM + 1;
				 * result[xc][yc] = true;
				 * 
				 * if ( currentCell.north ) { result[xc][yc + 1] = true; } if (
				 * currentCell.south ) { result[xc][yc - 1] = true; } if (
				 * currentCell.east ) { result[xc + 1][yc] = true; } if (
				 * currentCell.west ) { result[xc - 1][yc] = true; }
				 */
				boolean[][] room = new GenerateurRoom( TAILLE_ROOM )
						.getRoom( currentCell );
				applyRoom( result , room , i , j );
			}
		}
		// result
		return result;
	}

	private void applyRoom( boolean[][] pMap , boolean[][] pRoom , int pX ,
			int pY )
	{
		for ( int i = 0; i < pRoom[0].length; i++ )
		{
			for ( int j = 0; j < pRoom.length; j++ )
			{
				int x = i + pX * TAILLE_ROOM;
				int y = j + pY * TAILLE_ROOM;
				pMap[x][y] = pRoom[i][j];
				//System.out.println("x:"+x+",y="+y+",pRoom)"+pRoom[i][j]);
			}
		}

	}

}
